package com.mercury.auth.handler;

import com.mercury.base.constant.ResultCode;
import com.mercury.base.result.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * 权限异常
 *
 * @author mercury
 */
@RestControllerAdvice
@Slf4j
@Order(-1)
public class AuthExceptionHandler {

    /**
     * 用户不存在
     *
     * @param e 错误
     * @return 响应
     */
    @ResponseBody
    @ExceptionHandler(UsernameNotFoundException.class)
    public ResultVo<String> handleUsernameNotFoundException(HttpServletRequest request, UsernameNotFoundException e) {
        log.error("[UsernameNotFoundException]:request==>{},message==>{},e==>{}", request.getRequestURI(), e.getMessage(), e);
        return ResultVo.err(ResultCode.USER_NOT_EXIST);
    }

    /**
     * 用户名和密码异常
     *
     * @param e 错误
     * @return 响应
     */
    @ResponseBody
    @ExceptionHandler(InvalidGrantException.class)
    public ResultVo<String> handleInvalidGrantException(HttpServletRequest request, InvalidGrantException e) {
        log.error("[InvalidGrantException]:request==>{},message==>{},e==>{}", request.getRequestURI(), e.getMessage(), e);
        return ResultVo.err(ResultCode.USERNAME_OR_PASSWORD_ERROR);
    }

    /**
     * 用户名和密码异常
     *
     * @param e 错误
     * @return 响应
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(InvalidClientException.class)
    public ResultVo<String> handleInvalidClientException(HttpServletRequest request, InvalidClientException e) {
        log.error("[InvalidClientException]:request==>{},message==>{},e==>{}", request.getRequestURI(), e.getMessage(), e);
        return ResultVo.err(ResultCode.CLIENT_AUTHENTICATION_FAILED);
    }



    @ResponseBody
    @ExceptionHandler(AccountExpiredException.class)
    public ResultVo<String> handleAccountExpiredException(HttpServletRequest request, AccountExpiredException e) {
        log.error("[AccountExpiredException]:request==>{},message==>{},e==>{}", request.getRequestURI(), e.getMessage(), e);
        return ResultVo.err(ResultCode.CLIENT_AUTHENTICATION_FAILED);
    }

    /**
     * 账户异常(禁用、锁定、过期)
     *
     * @param e 错误
     * @return 响应
     */
    @ResponseBody
    @ExceptionHandler({InternalAuthenticationServiceException.class})
    public ResultVo<String> handleInternalAuthenticationServiceException(HttpServletRequest request, InternalAuthenticationServiceException e) {
        log.error("[InternalAuthenticationServiceException]:request==>{},message==>{},e==>{}", request.getRequestURI(), e.getMessage(), e);
        return ResultVo.err(e.getMessage());
    }

    /**
     * token 无效或已过期
     *
     * @param e 错误
     * @return 响应
     */
    @ResponseBody
    @ExceptionHandler({InvalidTokenException.class})
    public ResultVo<String> handleInvalidTokenExceptionException(HttpServletRequest request, InvalidTokenException e) {
        log.error("[InvalidTokenException]:request==>{},message==>{},e==>{}", request.getRequestURI(), e.getMessage(), e);
        return ResultVo.err(e.getMessage());
    }

}
